package Semaphore;

import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @author : ZhuQi
 * @version : 时间:2022/8/1 9:24 版本:
 * Semaphore 的使用
 * example: 完成 I++ {@link #test1()}}
 */
public class Demo {

    /**
     * 测试内容: 使用 Semaphore 实现互斥锁完成 I++
     * 测试结果: i = 10
     */
    @Test
    public void test1() throws Exception {
        Semaphore semaphore = new Semaphore(1);
        ThreadGroup work = new ThreadGroup("work");
        Runnable runnable = new Runnable() {
            private int i = 0;
            @Override
            public void run() {
                try {
                    semaphore.acquire();
                    i++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            }
            @Override
            public String toString() {
                return "$classname{" +
                        "i=" + i +
                        '}';
            }
        };
        for (int i = 0; i < 10; i++) {
            new Thread(work, runnable).start();
        }
        while (true) {
            if (work.activeCount() == 0) {
                System.out.println(runnable.toString());
                break;
            }
        }
    }

    /**
     * 测试内容: 测试只允许3个线程在工作
     * 测试结果: 每次只有三个线程在开始任务
     */
    @Test
    public void test() throws Exception {
        Semaphore semaphore = new Semaphore(3);
        int n = 5;
        ThreadGroup worker = new ThreadGroup("worker");
        for (int i = 0; i < n; i++) {
            new Thread(worker,() -> {
                for (int j = 0; j < 5; j++) {
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + ":" + "开始工作");
                        TimeUnit.SECONDS.sleep(3);
                    } catch (InterruptedException e) {
                        System.out.println(e.getMessage());
                    } finally {
                        semaphore.release();
                        System.out.println(Thread.currentThread().getName() + ":" + "结束工作");
                    }
                }
            }, "thread-").start();
        }
        while (true) {
            if (worker.activeCount() == 0 ){
                System.out.println("任务完成");
                break;
            }
        }
    }

}
